package jvm.VMExecSubsystem;

import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodType;

import static java.lang.invoke.MethodHandles.lookup;

/**
 * @author msi
 * 该代码是在有 invokedynamic和java.lang.invoke 包之前的实现。
 */
public class GrandFatherTestCase_1 {

    class GrandFather {
        void thinking() {
            System.out.println("i am grandfather");
        }
    }

    class Father extends GrandFather {
        void thinking() {
            System.out.println("i am father");
        }
    }

    class Son extends Father {
        void thinking() {
            //请在这里填入合适的代码，不能修改其他地方的代码
            //实现调用祖父类的thinking()方法，
            //JDK7Update9 之前的办法
            try {
                MethodType mt = MethodType.methodType(void.class);
                MethodHandle mh = lookup().findSpecial(GrandFather.class,
                        "thinking", mt, getClass());
                mh.invoke(this);
            } catch (Throwable e) {
            }
            //办法end
        }
    }

    public static void main(String[] args) {
        (new GrandFatherTestCase_1().new Son()).thinking();
    }

}
/**
 * 运行结果 i am father
 * 其实这个要求的难点在于，子类无法直接访问到祖父类，通过关键字super只能访问到父类实例对象，也就是说Son类的thinking方法中根本无法获取到一个实际类型是GrandFather的对象引用(除了new)。而invokevirtual
 * 指令的分派逻辑是固定的，只能按照方法接收者的实际类型去分派，这个程序员无法改变，在JDK7Update9 之前运行这段代码倒是可以获取祖父类的方法，但是在Update10只会就将这个bug修复了，现在只能获取到父类中的方法。
 * 解决方案见 GrandFatherTestCase_2
 */